package main

// 416. 分割等和子集
func main() {

}

func canPartition(nums []int) bool {
	// 二维动态规划，记录每个值，和前面的值参与、不参与得到的和，是否可以为数值J
	numLen := len(nums)
	if numLen < 2 {
		return false
	}

	numsSum := 0
	for _, i := range nums {
		numsSum += i
	}
	if numsSum%2 != 0 {
		return false
	}

	target := numsSum / 2
	dp := make([][]bool, numLen)

	for i := 0; i < numLen; i++ {
		dp[i] = make([]bool, target+1)
		dp[i][0] = true
	}

	if nums[0] > target {
		return false
	}
	dp[0][nums[0]] = true

	for i := 1; i < numLen; i++ {
		for j := 1; j <= target; j++ {
			// 怎么判定在i点凑j的钱成立呢？ 一个是i自身参与，一个是i自身不参与，往回找
			hasIBool := false
			if j >= nums[i] {
				hasIBool = dp[i-1][j-nums[i]]
			}
			dp[i][j] = dp[i-1][j] || hasIBool
		}
	}

	return dp[numLen-1][target]
}

/*
给你一个 只包含正整数 的 非空 数组 nums 。请你判断是否可以将这个数组分割成两个子集，使得两个子集的元素和相等。

示例 1：

输入：nums = [1,5,11,5]
输出：true
解释：数组可以分割成 [1, 5, 5] 和 [11] 。
示例 2：

输入：nums = [1,2,3,5]
输出：false
解释：数组不能分割成两个元素和相等的子集。

提示：

1 <= nums.length <= 200
1 <= nums[i] <= 100
*/
